package com.jmp.security;

import com.alibaba.fastjson.JSON;
import com.jmp.security.base.*;
import lombok.extern.slf4j.Slf4j;
import one.stand.entity.TokenEntity;

import java.util.Objects;

@Slf4j
public class DefaultAuthenticationManager<T extends RequestDetail> implements AuthenticationManager<T> {
    private ClientDetailService clientDetailService;
    private UserDetailService<T> userDetailService;
    private UserDetailValidService<T> userDetailValidService;
    private TokenEntityService tokenEntityService;
    private ResponseHandler successResponseHandler;
    private ResponseHandler failResponseHandler;

    public DefaultAuthenticationManager(ClientDetailService clientDetailService, UserDetailService<T> userDetailService, UserDetailValidService<T> userDetailValidService, TokenEntityService tokenEntityService, ResponseHandler successResponseHandler, ResponseHandler failResponseHandler) {
        this.clientDetailService = clientDetailService;
        this.userDetailService = userDetailService;
        this.userDetailValidService = userDetailValidService;
        this.tokenEntityService = tokenEntityService;
        this.successResponseHandler = successResponseHandler;
        this.failResponseHandler = failResponseHandler;
    }

    @Override
    public ResponseDetail authentication(T requestDetail) {
        ClientDetail clientDetail = null;
        UserDetail userDetail = null;
        TokenEntity tokenEntity = null;
        ResponseDetail responseDetail = null;
        try {

            if (log.isDebugEnabled()) {
                log.info("request builder: {}", JSON.toJSONString(requestDetail));
            }

            requestDetail.initAfter();

            // 获取请求端信息
            clientDetail = Objects.nonNull(clientDetailService) ? clientDetailService.get(requestDetail) : null;

            // 获取用户信息
            userDetail = userDetailService.get(requestDetail, clientDetail);
            userDetailValidService.check(requestDetail, clientDetail, userDetail);

            // 获取Token（通行凭证）
            tokenEntity = tokenEntityService.create(requestDetail, clientDetail, userDetail);

            // 组织返回
            responseDetail = successResponseHandler.handler(requestDetail, clientDetail, userDetail, tokenEntity, null);
        } catch (Exception e) {
            //异常处理
            responseDetail = failResponseHandler.handler(requestDetail, clientDetail, userDetail, tokenEntity, e);
        }

        if (log.isDebugEnabled()) {
            log.info("response builder: {}", JSON.toJSONString(responseDetail));
        }

        return responseDetail;
    }
}
